package com.lagou.edu.utils;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description: 扫描类.
 *
 * @author Wengy
 * @since JDK 1.8
 * @since 1.0.0
 */
public class JavaScan {
  
  /**
   * Description: 获取rootPath的相关的根路径
   * @return rootPath的相关的根路径
   * @throws Exception
   */
  public static String getRootPath() throws IOException {

    Enumeration<URL> resources = JavaScan.class.getClassLoader().getResources("");
    URL url = resources.nextElement();
    return url.getPath();
  }
  
  /**
   * 使用 IO扫描 Class文件
   */
  public static List<String> listClassName(String scanPath, List<String> classNameList) throws IOException {
    
    String rootPath = getRootPath();
    if(classNameList==null) {
      classNameList = new ArrayList<>();
    }
    
    File file = new File(scanPath);
    // 获取所有文件和文件夹
    File[] fileList = file.listFiles();
    for (int i = 0; null != fileList && i < fileList.length; i++) {
      String path = fileList[i].getPath();
      // 如果是目录
      if (fileList[i].isDirectory()) {
        // 继续递归
        listClassName(path, classNameList);
      }
      if (fileList[i].isFile()) {
        
        // 拼接类路径保存到集合中，(类路径所指的是 去掉根路径以外的项目中 class 的全路径)
        String classpath = path.replace(rootPath, "").replaceAll(".class", "")
            .replaceAll(File.separator, ".");
        classNameList.add(classpath);
      }
    }
    return classNameList;
  }
  
  /**
   * 使用 所有类全命名来 初始化容器
   *
   * @throws Exception
   */
  public static Map<String, Class<?>> getClazzMap(String packageName) throws Exception {
   
    String rootPath = getRootPath();
    String scanPath = rootPath + packageName.replace(".", File.separator);
    List<String> classNameList = listClassName(scanPath, null);
  
    Map<String, Class<?>> clazzMap = new HashMap<>(16);
    
    if (null == classNameList || classNameList.size() <= 0) {
      throw new Exception("文件路径不存在！" + JavaScan.class.getName());
    }
    
    // 获取 所有类的类全名
    for (int i = 0; i < classNameList.size(); i++) {
      
      String className = classNameList.get(i);
      Class<?> clazz = Class.forName(className);
      
      // 初始化限制，初始化的文件类型必须是 class文件
      if (!clazz.isAnnotation() && !clazz.isEnum() && !clazz.isInterface()) {
  
        // 初始化类对象 添加到容器中
        if (!clazzMap.containsKey(className)) {
          clazzMap.put(className, clazz);
        }
        
      }
    }
    return clazzMap;
  }
  
  /**
   * 测试
   *
   * @param args
   * @throws Exception
   */
  public static void main(String[] args) throws Exception {
    
    Map map = JavaScan.getClazzMap("com.lagou.edu.service");
  
    System.out.println("@@@@@@@@@@@@@@");
  }
  
}